﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;
using HYCodeBase.WinForm;
using HyDrawSelectArea;
using HYView;

namespace YArchitech.HVAC
{
	public class SplitPipeOperation
	{
		public SplitPipeOperation(Autodesk.Revit.DB.Document doc, UIDocument UiDoc, UIApplication UiApp, ExternalCommandData CommandData)
		{
			this.doc = doc;
			this.UiDoc = UiDoc;
			this.UiApp = UiApp;
			this.CommandData = CommandData;
		}

		public void SplitLinePipe(Element ele, FrmSplitPipe frm, Transaction tran)
		{
			List<Element> linePipeInProject = this.GetLinePipeInProject(ele, frm);
			tran.Start();
			this.SplitOperate(linePipeInProject, frm);
			this.doc.Regenerate();
			tran.Commit();
			this.SetNumForLinePipes(this.doc, frm, true);
		}

		private void SplitOperate(List<Element> LinePipes, FrmSplitPipe frm)
		{
			foreach (Element element in LinePipes)
			{
				if (element is MEPCurve && !this.SplitLineOperate<MEPCurve>((MEPCurve)element, frm))
				{
					break;
				}
			}
		}

		public void setNum(bool isBySys = true)
		{
			List<MEPCurve> list = YJKElementFilter.GetElementByClass(typeof(Pipe), this.doc).Cast<MEPCurve>().ToList<MEPCurve>();
			List<MEPCurve> list2 = YJKElementFilter.GetElementByClass(typeof(Duct), this.doc).Cast<MEPCurve>().ToList<MEPCurve>();
			if (list != null && list.Count<MEPCurve>() > 0)
			{
				this.linesForNum.AddRange(list);
				this.SetNumForLinePipes(this.doc, null, isBySys);
			}
			if (list2 != null && list2.Count<MEPCurve>() > 0)
			{
				this.linesForNum.Clear();
				this.linesForNum.AddRange(list2);
				this.SetNumForLinePipes(this.doc, null, isBySys);
			}
			if (!isBySys)
			{
				List<MEPCurve> list3 = YJKElementFilter.GetElementByClass(typeof(Conduit), this.doc).Cast<MEPCurve>().ToList<MEPCurve>();
				List<MEPCurve> list4 = YJKElementFilter.GetElementByClass(typeof(CableTray), this.doc).Cast<MEPCurve>().ToList<MEPCurve>();
				if (list3 != null && list3.Count<MEPCurve>() > 0)
				{
					this.linesForNum.Clear();
					this.linesForNum.AddRange(list3);
					this.SetNumForLinePipes(this.doc, null, false);
				}
				if (list4 != null && list4.Count<MEPCurve>() > 0)
				{
					this.linesForNum.Clear();
					this.linesForNum.AddRange(list4);
					this.SetNumForLinePipes(this.doc, null, false);
				}
			}
		}

		private List<Element> GetElementByCategory(Autodesk.Revit.DB.Document doc, Type type, BuiltInCategory builtInCategory)
		{
			return new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(type).OfCategory(builtInCategory).ToElements().ToList<Element>();
		}

		private List<Element> GetElementByClass(Type type, Autodesk.Revit.DB.Document doc)
		{
			return new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(type).ToElements().ToList<Element>();
		}

		public void delNum()
		{
			List<Element> list = new List<Element>();
			List<Element> elementByCategory = this.GetElementByCategory(this.doc, typeof(IndependentTag), BuiltInCategory.OST_DuctTags);
			List<Element> elementByCategory2 = this.GetElementByCategory(this.doc, typeof(IndependentTag), BuiltInCategory.OST_PipeTags);
			List<Element> elementByCategory3 = this.GetElementByCategory(this.doc, typeof(IndependentTag), BuiltInCategory.OST_ConduitTags);
			List<Element> elementByCategory4 = this.GetElementByCategory(this.doc, typeof(IndependentTag), BuiltInCategory.OST_CableTrayTags);
			if (elementByCategory != null && elementByCategory.Count<Element>() > 0)
			{
				list.AddRange(elementByCategory);
			}
			if (elementByCategory2 != null && elementByCategory2.Count<Element>() > 0)
			{
				list.AddRange(elementByCategory2);
			}
			if (elementByCategory3 != null && elementByCategory3.Count<Element>() > 0)
			{
				list.AddRange(elementByCategory3);
			}
			if (elementByCategory4 != null && elementByCategory4.Count<Element>() > 0)
			{
				list.AddRange(elementByCategory4);
			}
			Transaction transaction = new Transaction(this.doc, "删除标签");
			transaction.Start();
			foreach (Element element in list)
			{
				if (element.Name == "风管管段标注" || element.Name == "水管管段标注" || element.Name == "水管管段标注_无系统" || element.Name == "风管管段标注_无系统" || element.Name == "线管管段标注_无系统" || element.Name == "桥架管段标注_无系统")
				{
					this.doc.Delete(element.Id);
				}
			}
			transaction.Commit();
			List<Element> list2 = new List<Element>();
			List<Element> elementByClass = this.GetElementByClass(typeof(Pipe), this.doc);
			List<Element> elementByClass2 = this.GetElementByClass(typeof(Duct), this.doc);
			List<Element> elementByClass3 = this.GetElementByClass(typeof(Conduit), this.doc);
			List<Element> elementByClass4 = this.GetElementByClass(typeof(CableTray), this.doc);
			if (elementByClass != null && elementByClass.Count<Element>() > 0)
			{
				list2.AddRange(elementByClass);
			}
			if (elementByClass2 != null && elementByClass2.Count<Element>() > 0)
			{
				list2.AddRange(elementByClass2);
			}
			if (elementByClass3 != null && elementByClass3.Count<Element>() > 0)
			{
				list2.AddRange(elementByClass3);
			}
			if (elementByClass4 != null && elementByClass4.Count<Element>() > 0)
			{
				list2.AddRange(elementByClass4);
			}
			Transaction transaction2 = new Transaction(this.doc, "设置分段编号");
			transaction2.Start();
			foreach (Element elem in list2)
			{
				Parameter parameter = elem.GetParameter("分段编号");
				if (parameter != null && !parameter.IsReadOnly)
				{
					parameter.Set("");
				}
			}
			transaction2.Commit();
		}

		private void getAllLinkCurve(MEPCurve line, ref List<MEPCurve> allLinkCurve)
		{
			SearchBranch searchBranch = new SearchBranch(new ElementNode(line));
			searchBranch.DoSearch();
			ElementNode listRoot = searchBranch.GetListRoot();
			searchBranch.GetAllElement(listRoot, ref allLinkCurve);
		}

		private void getLetUpPoint(List<MEPCurve> listLinkCurve, ref double x, ref double y)
		{
			foreach (MEPCurve curve in listLinkCurve)
			{
				double num = 0.0;
				double num2 = 0.0;
				if (this.getCurvePoint(curve, ref num, ref num2))
				{
					if (num < x)
					{
						x = num;
					}
					if (num2 > y)
					{
						y = num2;
					}
				}
			}
		}

		private bool getCurvePoint(MEPCurve curve, ref double x, ref double y)
		{
			LocationCurve locationCurve = curve.Location as LocationCurve;
			if (!(locationCurve.Curve is Line))
			{
				return false;
			}
			Line line = locationCurve.Curve as Line;
			x = line.GetEndPoint(0).X;
			y = line.GetEndPoint(0).Y;
			if (line.GetEndPoint(1).X < x)
			{
				x = line.GetEndPoint(1).X;
			}
			if (line.GetEndPoint(1).Y < y)
			{
				y = line.GetEndPoint(1).Y;
			}
			return true;
		}

		private List<MEPCurve> getElementNodeCount(MEPCurve line)
		{
			List<MEPCurve> list = new List<MEPCurve>();
			SearchBranch searchBranch = new SearchBranch(line);
			searchBranch.DoSearch();
			ElementNode listRoot = searchBranch.GetListRoot();
			list.Add((MEPCurve)listRoot.Element);
			this.addMEPCurve(ref list, listRoot.Next, true);
			return list;
		}

		private void addMEPCurve(ref List<MEPCurve> res, ElementNode eNode, bool isNext = true)
		{
			if (eNode == null)
			{
				return;
			}
			if (!(eNode.Element is FamilyInstance))
			{
				res.Add((MEPCurve)eNode.Element);
				this.addMEPCurve(ref res, eNode.Next, true);
				return;
			}
			if (eNode.SubElementNode != null && eNode.SubElementNode.Count > 0)
			{
				List<MEPCurve> list = new List<MEPCurve>();
				this.addMEPCurve(ref list, eNode.Next, true);
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					List<MEPCurve> list2 = new List<MEPCurve>();
					this.addMEPCurve(ref list2, eNode2, true);
					if (list.Count <= list2.Count)
					{
						list = list2;
					}
				}
				res.AddRange(list);
				return;
			}
			this.addMEPCurve(ref res, eNode.Next, true);
		}

		private MEPCurve getStartCurve(List<MEPCurve> startList)
		{
			Dictionary<double, MEPCurve> dictionary = new Dictionary<double, MEPCurve>();
			startList.FirstOrDefault<MEPCurve>();
			foreach (MEPCurve mepcurve in startList)
			{
				if (mepcurve.ConnectorManager.Connectors.Size >= 1)
				{
					Connector connector = mepcurve.ConnectorManager.Connectors.AsEnumerable().First<Connector>();
					double key = 0.0;
					if (connector.Shape == null)
					{
						key = mepcurve.Diameter / 2.0 * Math.PI;
					}
                    else if ((int)connector.Shape == 1)
					{
						key = mepcurve.Width * mepcurve.Height;
					}
                    else if ((int)connector.Shape == 2)
					{
						key = mepcurve.Width * mepcurve.Height * Math.PI;
					}
					if (!dictionary.ContainsKey(key))
					{
						dictionary.Add(key, mepcurve);
					}
				}
			}
			return (from x in dictionary
			orderby x.Key descending
			select x).ToList<KeyValuePair<double, MEPCurve>>().First<KeyValuePair<double, MEPCurve>>().Value;
		}

		private List<MEPCurve> getStartPipe(List<MEPCurve> list)
		{
			return (from s in list
			where (from c in s.GetConnectors()
			where !c.IsConnected
			select c).Any<Connector>() || this.isRisePipe(s)
			select s).ToList<MEPCurve>();
		}

		private bool isRisePipe(MEPCurve c)
		{
			return c is Pipe && YJKRevitTools.isRiserPipe((Pipe)c);
		}

		private bool SplitLineOperate<T>(T pipe, FrmSplitPipe frm) where T : MEPCurve
		{
			YJKPiping<T> hypiping = new YJKPiping<T>(pipe);
			int num = 1;
			List<T> list = null;
			List<XYZ> separateXYZ = this.getSeparateXYZ(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin, frm);
			FamilySymbol currentFs = this.getCurrentFs(frm);
			if (currentFs == null)
			{
				YJKMessageBox.Information("没有找到对应的连接件，请选择存在的连接件！");
				return false;
			}
			ElementId fsId = this.setLinesDefaultUnion<T>(pipe, currentFs.Id);
			List<MEPCurve> list2 = new List<MEPCurve>();
			if (separateXYZ != null && separateXYZ.Count == 0)
			{
				list2.Add(pipe);
			}
			else
			{
				foreach (XYZ xyz in separateXYZ)
				{
					if (num == 1)
					{
						list = hypiping.Separate(xyz);
					}
					else if (list != null)
					{
						list = this.SeparateByLine<T>(list, xyz);
					}
					this.ConnectLine<T>(ref list, xyz, frm, currentFs.Id);
					list2.Add(list.ElementAt(0));
					list2.Add(list.ElementAt(1));
					num++;
				}
			}
			this.setAllLinesDefaultUnion(fsId, list2);
			return true;
		}

		private XYZ getClosePt(YJKPiping<MEPCurve> pipe, bool IsStart, XYZ connPt)
		{
			bool isConnected = pipe.StartConnector.Connector.IsConnected;
			bool isConnected2 = pipe.EndConnector.Connector.IsConnected;
			if (IsStart)
			{
				if (!isConnected)
				{
					return pipe.StartConnector.Connector.Origin;
				}
				return pipe.EndConnector.Connector.Origin;
			}
			else
			{
				if (isConnected && isConnected2)
				{
					return connPt;
				}
				if (isConnected)
				{
					return pipe.StartConnector.Connector.Origin;
				}
				return pipe.EndConnector.Connector.Origin;
			}
		}

		private void setAllLinesDefaultUnion(ElementId fsId, List<MEPCurve> innerLinesForNum)
		{
			innerLinesForNum = (from s in innerLinesForNum
			where s.IsValidObject
			select s).ToList<MEPCurve>();
			foreach (MEPCurve mepcurve in innerLinesForNum)
			{
				if (mepcurve is Duct || mepcurve is Pipe)
				{
					this.ClearSegmentFitting((Autodesk.Revit.DB.ElementType)this.doc.GetElement(mepcurve.GetTypeId()), fsId);
				}
				else
				{
					this.ClearCDSegmentFitting(mepcurve, fsId);
				}
			}
			this.linesForNum.AddRange(innerLinesForNum);
		}

		private ElementId setLinesDefaultUnion<T>(T line, ElementId fsID) where T : MEPCurve
		{
			if (line is Duct || line is Pipe)
			{
				return this.SetSegmentFitting((Autodesk.Revit.DB.ElementType)this.doc.GetElement(line.GetTypeId()), fsID, "活接头");
			}
			return this.SetSegmentCDFitting(line, fsID);
		}

		private void ClearSegmentFitting(Autodesk.Revit.DB.ElementType pipeType, ElementId elemId)
		{
			RoutingPreferenceManager routingPreferenceManager = ((MEPCurveType)pipeType).RoutingPreferenceManager;
            RoutingPreferenceRuleGroupType routingPreferenceRuleGroupType = (RoutingPreferenceRuleGroupType)5;
			int numberOfRules = routingPreferenceManager.GetNumberOfRules(routingPreferenceRuleGroupType);
			for (int i = 0; i < numberOfRules; i++)
			{
				if (elemId == routingPreferenceManager.GetRule(routingPreferenceRuleGroupType, i).MEPPartId || elemId == null || elemId.IntegerValue == -1)
				{
					routingPreferenceManager.RemoveRule(routingPreferenceRuleGroupType, i);
					return;
				}
			}
		}

		private void ClearCDSegmentFitting(MEPCurve line, ElementId elemId)
		{
			Parameter cdlineUnion = this.getCDlineUnion(line);
			if (cdlineUnion != null)
			{
				cdlineUnion.Set(elemId);
			}
		}

		private ElementId SetSegmentCDFitting(MEPCurve line, ElementId elemId)
		{
			ElementId result = null;
			Parameter cdlineUnion = this.getCDlineUnion(line);
			if (cdlineUnion != null)
			{
				result = cdlineUnion.AsElementId();
				cdlineUnion.Set(elemId);
			}
			return result;
		}

		private Parameter getCDlineUnion(MEPCurve line)
		{
			Parameter result = null;
			List<Parameter> list = ((Autodesk.Revit.DB.ElementType)this.doc.GetElement(line.GetTypeId())).GetParameters("活接头").ToList<Parameter>();
			if (list != null && list.Count > 0)
			{
				result = list.FirstOrDefault<Parameter>();
			}
			return result;
		}

		private ElementId SetSegmentFitting(Autodesk.Revit.DB.ElementType pipeType, ElementId elemId, string description)
		{
			ElementId result = null;
			RoutingPreferenceManager routingPreferenceManager = ((MEPCurveType)pipeType).RoutingPreferenceManager;
            RoutingPreferenceRuleGroupType routingPreferenceRuleGroupType = (RoutingPreferenceRuleGroupType)5;
			int numberOfRules = routingPreferenceManager.GetNumberOfRules(routingPreferenceRuleGroupType);
			for (int i = 0; i < numberOfRules; i++)
			{
				if (i == 0)
				{
					result = routingPreferenceManager.GetRule(routingPreferenceRuleGroupType, i).MEPPartId;
				}
				if (elemId == routingPreferenceManager.GetRule(routingPreferenceRuleGroupType, i).MEPPartId)
				{
					routingPreferenceManager.RemoveRule(routingPreferenceRuleGroupType, i);
					break;
				}
			}
			routingPreferenceManager.AddRule(routingPreferenceRuleGroupType, new RoutingPreferenceRule(elemId, description), 0);
			return result;
		}

		private void ConnectLine<T>(ref List<T> list, XYZ item, FrmSplitPipe frm, ElementId fsId) where T : MEPCurve
		{
			FamilyInstance familyInstance = this.doc.Create.NewUnionFitting(new YJKPiping<T>(list.ElementAt(0)).GetCloseConnector(item, false), new YJKPiping<T>(list.ElementAt(1)).GetCloseConnector(item, false));
			if (familyInstance.GetTypeId().IntegerValue != fsId.IntegerValue)
			{
				familyInstance.ChangeTypeId(fsId);
			}
		}

		private FamilySymbol getCurrentFs(FrmSplitPipe frm)
		{
			FamilySymbol familySymbolyByName;
			if (frm.radiob4.Checked)
			{
				string str = (frm.cmbProjectType.SelectedItem == null) ? "" : frm.cmbProjectType.SelectedItem.ToString();
				familySymbolyByName = this.GetFamilySymbolyByName("Fitting", str + ".rfa", frm.FsName);
			}
			else
			{
				string str = (frm.cmbCommonType.SelectedItem == null) ? "" : frm.cmbCommonType.SelectedItem.ToString();
				familySymbolyByName = this.GetFamilySymbolyByName("Fitting", str + ".rfa", "标准");
			}
			return familySymbolyByName;
		}

		public FamilySymbol GetFamilySymbolyByName(string typeName, string familyName, string symbolName = "标准", BuiltInCategory cate = (Autodesk.Revit.DB.BuiltInCategory)(-1))
		{
			FamilySymbol familySymbol = null;
			familyName = familyName.Replace(": 标准", "");
			string text = Path.Combine(Product.FamilyLocation, RevitVersion.GetVersionNumber(this.doc), typeName, familyName);
			Family family = null;
			SubTransaction subTransaction = null;
			try
			{
				List<Element> list = new List<Element>();
                if ((int)cate == -1)
				{
					List<Element> elementByCategory = YJKElementFilter.GetElementByCategory(this.doc, typeof(FamilySymbol), BuiltInCategory.OST_PipeFitting);
					List<Element> elementByCategory2 = YJKElementFilter.GetElementByCategory(this.doc, typeof(FamilySymbol), BuiltInCategory.OST_ConduitFitting);
					List<Element> elementByCategory3 = YJKElementFilter.GetElementByCategory(this.doc, typeof(FamilySymbol), BuiltInCategory.OST_CableTrayFitting);
					List<Element> elementByCategory4 = YJKElementFilter.GetElementByCategory(this.doc, typeof(FamilySymbol), BuiltInCategory.OST_DuctFitting);
					list.AddRange(elementByCategory);
					list.AddRange(elementByCategory2);
					list.AddRange(elementByCategory3);
					list.AddRange(elementByCategory4);
				}
				else
				{
					List<Element> elementByCategory5 = YJKElementFilter.GetElementByCategory(this.doc, typeof(FamilySymbol), cate);
					list.AddRange(elementByCategory5);
				}
				foreach (Element element in list)
				{
					if ((element as FamilySymbol).Family.Name == familyName.Substring(0, familyName.IndexOf(".")) && (element as FamilySymbol).Name == symbolName)
					{
						FamilySymbol result;
						familySymbol = (result = (element as FamilySymbol));
						return result;
					}
					if ((element as FamilySymbol).Family.Name == familyName.Substring(0, familyName.IndexOf(".")))
					{
						familySymbol = (element as FamilySymbol);
					}
				}
				if (familySymbol != null)
				{
					return familySymbol;
				}
				subTransaction = new SubTransaction(this.doc);
				subTransaction.Start();
				MyFamilyLoadOptions myFamilyLoadOptions = new MyFamilyLoadOptions();
				this.doc.LoadFamily(text, myFamilyLoadOptions, out family);
				subTransaction.Commit();
			}
			catch (Exception)
			{
			}
			finally
			{
				if (subTransaction != null && (int)subTransaction.GetStatus() != 3)
				{
					subTransaction.RollBack();
				}
			}
			if (family != null)
			{
				foreach (FamilySymbol familySymbol2 in family.GetSymbols())
				{
					if (familySymbol2.Family.Name == familyName.Substring(0, familyName.IndexOf(".")) && familySymbol2.Name == symbolName)
					{
						familySymbol = familySymbol2;
						break;
					}
				}
			}
			return familySymbol;
		}

		private List<T> SeparateByLine<T>(List<T> list, XYZ item) where T : MEPCurve
		{
			List<T> list2 = null;
			if (list != null && list.Count == 2)
			{
				YJKPiping<T> hypiping = new YJKPiping<T>(list.ElementAt(0));
				YJKPiping<T> hypiping2 = new YJKPiping<T>(list.ElementAt(1));
				list2 = hypiping.Separate(item);
				if (list2 == null)
				{
					list2 = hypiping2.Separate(item);
				}
			}
			return list2;
		}

		private List<XYZ> getSeparateXYZ(XYZ startPt, XYZ endPt, FrmSplitPipe frm)
		{
			List<XYZ> list = new List<XYZ>();
			XYZ xyz = (endPt - startPt).Normalize();
			double num = NumbericTools.mmToFeet(Convert.ToDouble(string.IsNullOrEmpty(frm.hyTextBox2.Text) ? "0" : frm.hyTextBox2.Text) * 1000.0);
			double num2 = NumbericTools.mmToFeet(Convert.ToDouble(string.IsNullOrEmpty(frm.hyTextBox3.Text) ? "0" : frm.hyTextBox3.Text) * 1000.0);
			double length = (endPt - startPt).GetLength();
			if (length - num > 0.001)
			{
				int num3 = (int)(length / num);
				if (length % num > num2)
				{
					for (int i = 1; i <= num3; i++)
					{
						list.Add(startPt + (double)i * xyz * num);
					}
				}
				else if (length % num > 0.01)
				{
					for (int j = 1; j <= num3; j++)
					{
						if (j == num3)
						{
							list.Add(startPt + (length + (double)(num3 - 1) * num) / 2.0 * xyz);
						}
						else
						{
							list.Add(startPt + (double)j * xyz * num);
						}
					}
				}
			}
			return list;
		}

		public void DeletNum(List<MEPCurve> elems)
		{
			foreach (Element element in ((IEnumerable<Element>)new FilteredElementCollector(this.doc, this.doc.ActiveView.Id).OfClass(typeof(IndependentTag)).ToList<Element>()))
			{
				IndependentTag independentTag = element as IndependentTag;
				ElementId tagOwnerId = independentTag.TaggedLocalElementId;
				if (elems.FirstOrDefault((MEPCurve x) => x.Id == tagOwnerId) != null)
				{
					this.doc.Delete(independentTag.Id);
					Parameter parameter = this.doc.GetElement(tagOwnerId).GetParameters("分段编号").FirstOrDefault<Parameter>();
					if (parameter != null && !parameter.IsReadOnly)
					{
						parameter.Set("");
					}
				}
			}
		}

		private void reSortListAndCreateTag_ByPipe(List<MEPCurve> list, FamilySymbol fs)
		{
			if (list == null || list.Count<MEPCurve>() == 0)
			{
				return;
			}
			this.DeletNum(list);
			List<List<MEPCurve>> list2 = new List<List<MEPCurve>>();
			List<MEPCurve> list3 = new List<MEPCurve>();
			List<MEPCurve> list4 = new List<MEPCurve>();
			list3.AddRange(list);
			using (List<MEPCurve>.Enumerator enumerator = list.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					MEPCurve line = enumerator.Current;
					if (list4.FirstOrDefault((MEPCurve x) => x.Id == line.Id) == null)
					{
						List<MEPCurve> list5 = new List<MEPCurve>();
						this.getAllLinkCurve(line, ref list5);
						list2.Add(list5);
						list4.AddRange(list5);
						if (list4.Count == list.Count)
						{
							break;
						}
					}
				}
			}
			Dictionary<XYZ, List<MEPCurve>> dictionary = new Dictionary<XYZ, List<MEPCurve>>();
			Dictionary<int, List<MEPCurve>> dictionary2 = new Dictionary<int, List<MEPCurve>>();
			if (list2.Count > 1)
			{
				foreach (List<MEPCurve> list6 in list2)
				{
					MEPCurve curve = list6.FirstOrDefault<MEPCurve>();
					double num = 0.0;
					double num2 = 0.0;
					this.getCurvePoint(curve, ref num, ref num2);
					this.getLetUpPoint(list6, ref num, ref num2);
					XYZ key = new XYZ(num, num2, 0.0);
					dictionary.Add(key, list6);
				}
				List<XYZ> list7 = (from x in dictionary.Keys.ToList<XYZ>()
				orderby x.Y descending, x.X
				select x).ToList<XYZ>();
				int num3 = 0;
				using (List<XYZ>.Enumerator enumerator3 = list7.GetEnumerator())
				{
					while (enumerator3.MoveNext())
					{
						XYZ key2 = enumerator3.Current;
						List<MEPCurve> value = new List<MEPCurve>();
						if (dictionary.TryGetValue(key2, out value))
						{
							num3++;
							dictionary2.Add(num3, value);
						}
					}
					goto IL_1F8;
				}
			}
			dictionary2.Add(1, list);
			IL_1F8:
			foreach (int num4 in dictionary2.Keys.ToList<int>())
			{
				List<MEPCurve> source = new List<MEPCurve>();
				if (dictionary2.TryGetValue(num4, out source))
				{
					int num5 = 1;
					new List<MEPCurve>();
					List<MEPCurve> startPipe = this.getStartPipe(source.ToList<MEPCurve>());
					MEPCurve startCurve = this.getStartCurve(startPipe);
					foreach (MEPCurve item in this.getElementNodeCount(startCurve))
					{
						this.setNewTag(item, num4, ref num5, fs);
					}
					this.setBranchNum(startCurve, num4, ref num5, fs);
				}
			}
		}

		private void reSortListAndCreateTag(List<MEPCurve> list, FamilySymbol fs)
		{
			if (list != null && list.Count<MEPCurve>() > 0 && (list.FirstOrDefault<MEPCurve>() is Pipe || list.FirstOrDefault<MEPCurve>() is Duct))
			{
				this.DeletNum(list);
				foreach (IGrouping<string, MEPCurve> source in from MEPCurve s in list
				group s by s.MEPSystem.Name)
				{
					int num = 1;
					List<MEPCurve> list2 = new List<MEPCurve>();
					List<MEPCurve> startPipe = this.getStartPipe(source.ToList<MEPCurve>());
					MEPCurve startLine = source.ToList<MEPCurve>().FirstOrDefault<MEPCurve>();
					foreach (MEPCurve mepcurve in startPipe)
					{
						List<MEPCurve> elementNodeCount = this.getElementNodeCount(mepcurve);
						if (elementNodeCount != null && list2 != null && elementNodeCount.Count >= list2.Count)
						{
							list2 = elementNodeCount;
							startLine = mepcurve;
						}
					}
					foreach (MEPCurve item in list2)
					{
						this.setNewTag(item, ref num, fs);
					}
					this.setBranchNum(startLine, ref num, fs);
				}
			}
		}

		private void setBranchNum(MEPCurve startLine, int listIndex, ref int index, FamilySymbol fs)
		{
			SearchBranch searchBranch = new SearchBranch(startLine);
			searchBranch.DoSearch();
			ElementNode listRoot = searchBranch.GetListRoot();
			Parameter parameter = listRoot.Element.GetParameter("分段编号");
			if (parameter != null && string.IsNullOrEmpty(parameter.AsString()) && !(listRoot.Element is FamilyInstance))
			{
				this.setNewTag((MEPCurve)listRoot.Element, listIndex, ref index, fs);
			}
			if (listRoot.Next != null)
			{
				this.setNextBranchNum(listRoot.Next, listIndex, ref index, fs, true);
			}
			if (listRoot.SubElementNode != null)
			{
				foreach (ElementNode eNode in listRoot.SubElementNode)
				{
					this.setNextBranchNum(eNode, listIndex, ref index, fs, true);
				}
			}
		}

		private void setBranchNum(MEPCurve startLine, ref int index, FamilySymbol fs)
		{
			SearchBranch searchBranch = new SearchBranch(startLine);
			searchBranch.DoSearch();
			ElementNode listRoot = searchBranch.GetListRoot();
			Parameter parameter = listRoot.Element.GetParameter("分段编号");
			if (parameter != null && string.IsNullOrEmpty(parameter.AsString()))
			{
				this.setNewTag((MEPCurve)listRoot.Element, ref index, fs);
			}
			if (listRoot.Next != null)
			{
				this.setNextBranchNum(listRoot.Next, ref index, fs);
			}
			if (listRoot.SubElementNode != null)
			{
				foreach (ElementNode eNode in listRoot.SubElementNode)
				{
					this.setNextBranchNum(eNode, ref index, fs);
				}
			}
		}

		private void setNextBranchNum(ElementNode eNode, int listIndex, ref int index, FamilySymbol fs, bool isNext = true)
		{
			if (eNode == null)
			{
				return;
			}
			Parameter parameter = eNode.Element.GetParameter("分段编号");
			if (parameter != null && string.IsNullOrEmpty(parameter.AsString()) && !(eNode.Element is FamilyInstance))
			{
				this.setNewTag((MEPCurve)eNode.Element, listIndex, ref index, fs);
			}
			this.setNextBranchNum(eNode.Next, listIndex, ref index, fs, true);
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					this.setNextBranchNum(eNode2, listIndex, ref index, fs, true);
				}
			}
		}

		private void setNextBranchNum(ElementNode eNode, ref int index, FamilySymbol fs)
		{
			if (eNode == null)
			{
				return;
			}
			Parameter parameter = eNode.Element.GetParameter("分段编号");
			if (parameter != null && string.IsNullOrEmpty(parameter.AsString()))
			{
				this.setNewTag((MEPCurve)eNode.Element, ref index, fs);
			}
			this.setNextBranchNum(eNode.Next, ref index, fs);
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode eNode2 in eNode.SubElementNode)
				{
					this.setNextBranchNum(eNode2, ref index, fs);
				}
			}
		}

		private void setNewTag(MEPCurve item, int listIndex, ref int index, FamilySymbol fs)
		{
			(this.doc.GetElement(item.Id) as MEPCurve).GetParameter("分段编号").Set(listIndex + "-" + index);
			YJKPiping<MEPCurve> it = new YJKPiping<MEPCurve>(item);
			IndependentTag independentTag = RevitVersionFuncs.NewTag(this.doc, this.doc.ActiveView, new Reference(item), false, 0, 0, this.getLocation(it));
			AssociationMarkInfo.WriteMarkInfoToElement(independentTag, MarkType.PipeLine);
			if (fs != null)
			{
				independentTag.ChangeTypeId(fs.Id);
			}
			index++;
		}

		private void setNewTag(MEPCurve item, ref int index, FamilySymbol fs)
		{
			(this.doc.GetElement(item.Id) as MEPCurve).GetParameter("分段编号").Set("-" + index);
			YJKPiping<MEPCurve> it = new YJKPiping<MEPCurve>(item);
			IndependentTag independentTag = RevitVersionFuncs.NewTag(this.doc, this.doc.ActiveView, new Reference(item), false, 0, 0, this.getLocation(it));
			AssociationMarkInfo.WriteMarkInfoToElement(independentTag, MarkType.PipeLine);
			if (fs != null)
			{
				independentTag.ChangeTypeId(fs.Id);
			}
			index++;
		}

		private void SetNumForLinePipes(Autodesk.Revit.DB.Document doc, FrmSplitPipe frm, bool isBySys = true)
		{
			using (Transaction transaction = new Transaction(doc, "设置标记"))
			{
				try
				{
					transaction.Start();
					this.addShareParam();
					new Dictionary<string, int>();
					bool flag = false;
					if (frm != null && frm.cbNumber.Checked && frm.rbNumberBySys.Checked)
					{
						flag = true;
					}
					else if (frm == null && isBySys)
					{
						flag = true;
					}
					if (flag && this.linesForNum.Count > 0 && (this.linesForNum.FirstOrDefault<MEPCurve>() is Pipe || this.linesForNum.FirstOrDefault<MEPCurve>() is Duct))
					{
						FamilySymbol familySymbolyByName;
						if (this.linesForNum.FirstOrDefault<MEPCurve>() is Pipe)
						{
							familySymbolyByName = this.GetFamilySymbolyByName("MarkTag", "水管管段标注.rfa", "水管管段标注", BuiltInCategory.OST_PipeTags);
						}
						else
						{
							familySymbolyByName = this.GetFamilySymbolyByName("MarkTag", "风管管段标注.rfa", "风管管段标注", BuiltInCategory.OST_DuctTags);
						}
						this.reSortListAndCreateTag(this.linesForNum, familySymbolyByName);
					}
					bool flag2 = false;
					if (frm != null && frm.cbNumber.Checked && frm.rbNumberByPipe.Checked)
					{
						flag2 = true;
					}
					else if (frm == null && !isBySys)
					{
						flag2 = true;
					}
					if (flag2 && this.linesForNum.Count > 0)
					{
						FamilySymbol familySymbolyByName2;
						if (this.linesForNum.FirstOrDefault<MEPCurve>() is Pipe)
						{
							familySymbolyByName2 = this.GetFamilySymbolyByName("MarkTag", "水管管段标注_无系统.rfa", "水管管段标注_无系统", BuiltInCategory.OST_PipeTags);
						}
						else if (this.linesForNum.FirstOrDefault<MEPCurve>() is Duct)
						{
							familySymbolyByName2 = this.GetFamilySymbolyByName("MarkTag", "风管管段标注_无系统.rfa", "风管管段标注_无系统", BuiltInCategory.OST_DuctTags);
						}
						else if (this.linesForNum.FirstOrDefault<MEPCurve>() is Conduit)
						{
							familySymbolyByName2 = this.GetFamilySymbolyByName("MarkTag", "线管管段标注_无系统.rfa", "线管管段标注_无系统", BuiltInCategory.OST_ConduitTags);
						}
						else
						{
							familySymbolyByName2 = this.GetFamilySymbolyByName("MarkTag", "桥架管段标注_无系统.rfa", "桥架管段标注_无系统", BuiltInCategory.OST_CableTrayTags);
						}
						this.reSortListAndCreateTag_ByPipe(this.linesForNum, familySymbolyByName2);
					}
					transaction.Commit();
				}
				catch (Exception)
				{
					if ((int)transaction.GetStatus() == 1)
					{
						transaction.RollBack();
					}
				}
			}
		}

		private XYZ getLocation(YJKPiping<MEPCurve> it)
		{
			XYZ xyz = (it.StartConnector.Origin - it.EndConnector.Origin) / 2.0 + it.EndConnector.Origin;
			XYZ xyz2 = YJKRevitTools.GetVectorByHorizontal((it.StartConnector.Origin - it.EndConnector.Origin).Normalize());
			if (Math.Abs(xyz2.Y) > 0.05)
			{
				if (xyz2.Y < 0.0)
				{
					xyz2 = -xyz2;
				}
			}
			else if (xyz2.X > 0.0)
			{
				xyz2 = -xyz2;
			}
			return xyz + xyz2 * 3.0;
		}

		private void addShareParam()
		{
			SubTransaction subTransaction = new SubTransaction(this.doc);
			try
			{
				subTransaction.Start();
				string text = Path.Combine(Product.DataLocation, "MarkTagShareParam.txt");
				if (!File.Exists(text))
				{
					subTransaction.RollBack();
				}
				else
				{
					List<string> listStr = null;
					CategorySet categories = null;
					this.GetCategorySetAndParameterNames(this.UiApp, ref categories, ref listStr);
					YJKRevitTools.SetInstanceParameter(this.UiApp, text, "管道标记", listStr, categories, false, BuiltInParameterGroup.PG_IDENTITY_DATA);
					subTransaction.Commit();
				}
			}
			catch (Exception)
			{
				subTransaction.RollBack();
			}
		}

		private void GetCategorySetAndParameterNames(UIApplication uiApp, ref CategorySet categories, ref List<string> listParameterNames)
		{
			categories = uiApp.Application.Create.NewCategorySet();
			listParameterNames = new List<string>();
			Category category = uiApp.ActiveUIDocument.Document.Settings.Categories.get_Item(BuiltInCategory.OST_DuctCurves);
			categories.Insert(category);
			category = uiApp.ActiveUIDocument.Document.Settings.Categories.get_Item(BuiltInCategory.OST_PipeCurves);
			categories.Insert(category);
			category = uiApp.ActiveUIDocument.Document.Settings.Categories.get_Item(BuiltInCategory.OST_CableTray);
			categories.Insert(category);
			category = uiApp.ActiveUIDocument.Document.Settings.Categories.get_Item(BuiltInCategory.OST_Conduit);
			categories.Insert(category);
			listParameterNames.Add("分段编号");
		}

		private List<Element> GetLinePipeInProject(Element ele, FrmSplitPipe frm)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			return (from s in this.GetSectionList(filteredElementCollector.OfClass(ele.GetType()).ToList<Element>(), frm)
			where ((HostObject)s).Name == ((HostObject)ele).Name
			select s).ToList<Element>();
		}

		private List<Element> GetSectionList(List<Element> lists, FrmSplitPipe frm)
		{
			List<Element> result = new List<Element>();
			if (frm.SectionType == SectionType.Area)
			{
				WindowHandle windowHandle = null;
				if (windowHandle == null)
				{
					windowHandle = new WindowHandle(Process.GetCurrentProcess().MainWindowHandle);
				}
				if (SelectAreaManager._hWndRevit == null)
				{
					SelectAreaManager._hWndRevit = windowHandle;
				}
				SelectAreaManager selectAreaManager = new SelectAreaManager(this.CommandData);
				if (selectAreaManager.EditOutLine() != null)
				{
					YJKMessageBox.Show("选择区域失败");
				}
				List<ElementId> lstDetailCurveId = selectAreaManager.m_lstDetailCurveId;
				CollectSelAreaElement collectSelAreaElement = new CollectSelAreaElement(this.UiApp);
				List<Element> eles = collectSelAreaElement.CollectAllElementInArea(false, this.doc.ActiveView, lstDetailCurveId);
				if (eles != null && eles.Count > 0)
				{
					result = (from s in lists
					where (from e in eles
					where e.Id == s.Id
					select e).Any<Element>()
					select s).ToList<Element>();
				}
				Transaction transaction = new Transaction(this.doc, "delete curve");
				transaction.Start();
				this.doc.Delete(lstDetailCurveId);
				transaction.Commit();
			}
			else if (frm.SectionType == SectionType.Level)
			{
				result = this.SectionLevel(lists);
			}
			else if (frm.SectionType == SectionType.Project)
			{
				result = lists;
			}
			return result;
		}

		private List<Element> SectionLevel(List<Element> res)
		{
			List<Level> list = new FilteredElementCollector(this.doc).OfClass(typeof(Level)).Cast<Level>().ToList<Level>();
			SelectFloorForm selectFloorForm = new SelectFloorForm(list);
			selectFloorForm.ShowDialog();
			List<int> list2 = selectFloorForm.SelectedViewIndexs();
			List<ElementId> SelectLevelIds = new List<ElementId>();
			foreach (int index in list2)
			{
				SelectLevelIds.Add(list.ElementAt(index).Id);
			}
			return (from s in res
			where SelectLevelIds.Contains(((MEPCurve)s).ReferenceLevel.Id)
			select s).ToList<Element>();
		}

		private Document doc;

		private UIDocument UiDoc;

		private List<MEPCurve> linesForNum = new List<MEPCurve>();

		private UIApplication UiApp;

		private ExternalCommandData CommandData;
	}
}
